package com.android.equipment.ui.dialog

import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.drawable.Drawable
import android.net.Uri
import android.widget.ImageView
import com.android.equipment.R
import com.android.equipment.adapter.WorkEvidenceAdapter
import com.android.equipment.custom.GridSpaceItemDecoration
import com.android.equipment.dao.WorkEvidence
import com.android.equipment.dao.operate.DaoWork
import com.android.equipment.dao.operate.DaoWorkEvidence
import com.android.equipment.databinding.DialogEvidenceBinding
import com.blankj.utilcode.util.StringUtils
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.CustomTarget
import com.bumptech.glide.request.transition.Transition
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.PictureMimeType
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.engine.CompressFileEngine
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnBitmapWatermarkEventListener
import com.luck.picture.lib.interfaces.OnKeyValueResultCallbackListener
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.luck.picture.lib.utils.DateUtils
import com.luck.picture.lib.utils.PictureFileUtils
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.core.BottomPopupView
import com.lxj.xpopup.interfaces.XPopupImageLoader
import top.zibin.luban.CompressionPredicate
import top.zibin.luban.Luban
import top.zibin.luban.OnNewCompressListener
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale


class EvidenceDialog(context: Context, val currentWorkId: Long) :
    BottomPopupView(context) {
    lateinit var binding: DialogEvidenceBinding
    private val evidenceAdapter by lazy { WorkEvidenceAdapter(R.layout.item_evidence,DaoWork.getInstance().getWork(currentWorkId)) }
    override fun getImplLayoutId(): Int {
        return R.layout.dialog_evidence
    }

    override fun onCreate() {
        super.onCreate()
        binding = DialogEvidenceBinding.bind(popupImplView)
        initEvent()
        initRecycler()
        initData()
    }

    private fun initRecycler() {
        binding.rvEvidence.addItemDecoration(GridSpaceItemDecoration(4, 20, 20))
        binding.rvEvidence.adapter = evidenceAdapter
        evidenceAdapter.addChildClickViewIds(R.id.iv_delete,R.id.iv_pic)
        evidenceAdapter.setOnItemChildClickListener { adapter, view, position ->
            if (view.id == R.id.iv_delete) {
                XPopup.Builder(context)
                    .asConfirm("确认删除？", "删除后不可恢复") {
                        val item = adapter.getItem(position) as WorkEvidence
                        DaoWorkEvidence.getInstance().delWorkEvidence(item)
                        evidenceAdapter.removeAt(position)
                    }.show()
            }else if (view.id == R.id.iv_pic){
                XPopup.Builder(context)
                    .asImageViewer(view as ImageView,"file://" +(adapter.getItem(position) as WorkEvidence).picUrl,false,-1,-1,-1,false, object: XPopupImageLoader{
                        override fun loadImage(position: Int, uri: Any, imageView: ImageView) {
                            Glide.with(imageView.context).load(uri).into(imageView)
                        }

                        override fun getImageFile(context: Context, uri: Any): File {
                            TODO("Not yet implemented")
                        }


                    }
                    )
                    .show()
            }
        }
    }

    private fun initData() {
        DaoWorkEvidence.getInstance().getWorkEvidenceData(currentWorkId)?.let {
            if (it.isNotEmpty()) {
                evidenceAdapter.setList(it)
            }
        }

        val work = DaoWork.getInstance().getWork(currentWorkId)
        if (work.status == 2){
            binding.tvTakePhoto.visibility = GONE
        }
    }

    private fun initEvent() {
        binding.tvTakePhoto.setOnClickListener {
            PictureSelector.create(context)
                .openCamera(SelectMimeType.ofImage())
                .setCompressEngine(ImageFileCompressEngine())
                .setAddBitmapWatermarkListener(MeBitmapWatermarkEventListener(getSandboxMarkDir()))
                .forResult(object : OnResultCallbackListener<LocalMedia?> {
                    override fun onResult(result: ArrayList<LocalMedia?>?) {
                        val path = result?.get(0)?.availablePath
                        //watermarkPath
                        //compressPath
                        if (!StringUtils.isEmpty(path)) {
                            WorkEvidence().apply {
                                this.workId = currentWorkId
                                this.workName = DaoWork.getInstance().getWork(currentWorkId).name
                                this.picUrl = path
                                this.picTime = DateUtils.getYearDataFormat(System.currentTimeMillis())
                                DaoWorkEvidence.getInstance().addWorkEvidence(this)
                                evidenceAdapter.addData(this)
                            }
                        }
                    }

                    override fun onCancel() {
                    }
                })
        }

        binding.ivClose.setOnClickListener {
            dismiss()
        }
    }

    /**
     * 创建自定义输出目录
     *
     * @return
     */
    private fun getSandboxMarkDir(): String {
        val externalFilesDir = context.getExternalFilesDir("")
        val customFile = File(externalFilesDir!!.absolutePath, "Mark")
        if (!customFile.exists()) {
            customFile.mkdirs()
        }
        return customFile.absolutePath + File.separator
    }


    class MeBitmapWatermarkEventListener(private val targetPath: String) : OnBitmapWatermarkEventListener {

        override fun onAddBitmapWatermark(
            context: Context,
            srcPath: String,
            mimeType: String,
            call: OnKeyValueResultCallbackListener
        ) {
            // 使用 Glide 加载源图片
            Glide.with(context).asBitmap().sizeMultiplier(0.6f).load(srcPath)
                .into(object : CustomTarget<Bitmap?>() {
                    override fun onResourceReady(
                        resource: Bitmap,
                        transition: Transition<in Bitmap?>?
                    ) {
                        // 获取当前时间作为水印
                        val currentDateTime = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()).format(
                            Date()
                        )
                        val watermarkText = "Time: $currentDateTime"

                        // 创建一个新的 Bitmap，用于在其上绘制水印
                        val watermarkBitmap = resource.copy(Bitmap.Config.ARGB_8888, true)
                        val canvas = Canvas(watermarkBitmap)
                        val paint = Paint(Paint.ANTI_ALIAS_FLAG)
                        paint.color = Color.WHITE // 设置水印文字颜色
                        paint.textSize = 40f // 设置水印字体大小
                        paint.alpha = 120 // 设置水印透明度

                        // 在指定位置绘制水印
                        val x = 30f // X 坐标（可以调整）
                        val y = (watermarkBitmap.height - 30).toFloat() // Y 坐标（可以调整）
                        canvas.drawText(watermarkText, x, y, paint)

                        // 压缩水印图片
                        val stream = ByteArrayOutputStream()
                        watermarkBitmap.compress(Bitmap.CompressFormat.JPEG, 60, stream)

                        watermarkBitmap.recycle() // 释放内存

                        var fos: FileOutputStream? = null
                        var result: String? = null
                        try {
                            // 保存水印图像到目标路径
                            val targetFile = File(targetPath, DateUtils.getCreateFileName("Watermarked_") + ".jpg")
                            fos = FileOutputStream(targetFile)
                            fos.write(stream.toByteArray())
                            fos.flush()
                            result = targetFile.absolutePath
                        } catch (e: IOException) {
                            e.printStackTrace()
                        } finally {
                            PictureFileUtils.close(fos)
                            PictureFileUtils.close(stream)
                        }

                        // 回调返回结果
                        if (call != null) {
                            call.onCallback(srcPath, result)
                        }
                    }

                    override fun onLoadCleared(placeholder: Drawable?) {
                        if (call != null) {
                            call.onCallback(srcPath, "")
                        }
                    }
                })
        }
    }



    class ImageFileCompressEngine : CompressFileEngine {
        override fun onStartCompress(
            context: Context,
            source: ArrayList<Uri>,
            call: OnKeyValueResultCallbackListener
        ) {
            Luban.with(context).load(source).ignoreBy(100).setRenameListener { filePath ->
                val indexOf = filePath.lastIndexOf(".")
                val postfix = if (indexOf != -1) filePath.substring(indexOf) else ".jpg"
                DateUtils.getCreateFileName("CMP_") + postfix
            }.filter(CompressionPredicate { path ->
                if (PictureMimeType.isUrlHasImage(path) && !PictureMimeType.isHasHttp(path)) {
                    return@CompressionPredicate true
                }
                !PictureMimeType.isUrlHasGif(path)
            }).setCompressListener(object : OnNewCompressListener {
                override fun onStart() {
                }

                override fun onSuccess(source: String, compressFile: File) {
                    if (call != null) {
                        call.onCallback(source, compressFile.absolutePath)
                    }
                }

                override fun onError(source: String, e: Throwable) {
                    if (call != null) {
                        call.onCallback(source, null)
                    }
                }
            }).launch()
        }
    }


}